<template>
    <div class="goods-sku">
      <dl v-for="item in goods.specs" :key="item.id">
        <dt>{{item.name}}</dt>
        <dd>
            <template v-for="val in item.values" :key="val.name">
                <img :class="{selected: val.selected, disabled: val.disabled}" v-if="val.picture" :src="val.picture" alt="" :title="val.name" @click="changeState(item, val)">
                <span :class="{selected: val.selected, disabled: val.disabled}" v-else  @click="changeState(item, val)">{{val.name}}</span>
            </template>
        </dd>
      </dl>
    </div>
  </template>
  <script>
  export default {
    name: 'GoodsSku',
    props: {
        goods: {
            type: Object,
            default: () => ({})
        },
        //商品组合id
        skuId: {
            type: String,
            default: ''
        }
    },
    setup (props, {emit}) {
        const pathMap = getPathMap (props.goods.skus)
        //初始化时默认选中的组合
        if(props.skuId) {
            defaultData(props.goods, props.skuId)
         }
        //组件初始化时更新禁用状态
        updateDisabledStatus(props.goods.specs, pathMap)
        const changeState = (item, val) => {
            //如果是禁用状态不作为
            if(val.disabled) return false
            //如果已选中，再次点击为取消
            if(val.selected) {
                val.selected = false
            } else {
                item.values.forEach(valItem => {
                    valItem.selected = false
                })
                val.selected = true
            }
            //点击时更新禁用状态
            updateDisabledStatus(props.goods.specs, pathMap)

            //将选择的sku信息通知父组件
            //选择完整的sku按钮，才可以拿到sku信息
            //不完整的sku组合按钮，提交空对象给父组件

            //得到当前选中的组合,过滤掉udefined
            const selectedArr = getSelectedArr(props.goods.specs).filter(v => v)
            if(selectedArr.length === props.goods.specs.length) {
                //完整组合情况
                //获取路径字典里的id
                const skuIds = pathMap[selectedArr.join(spliter)]
                //得到sku信息
                const sku = props.goods.skus.find(sku => sku.id === skuIds[0])
                //把sku信息传递给父组件
                emit('change', {
                    skuId: sku.id,
                    price: sku.price,
                    oldPrice: sku.oldPrice,
                    inventory: sku.inventory,
                    specsText: sku.specs.reduce((p, n) => `${p} ${n.name}：${n.valueName}`, '').trim()
                })
            } else {
                //不完整情况
              emit('change', {})

            }

        }
        return {changeState}
    }
  }
  //默认选中的组合
  const defaultData = (goods, skuId) => {
    const sku = goods.skus.find(sku => sku.id === skuId)
    if(sku) {
        goods.specs.forEach((item, i) => {
            const value = sku.specs[i].valueName
            item.values.forEach(val => {
                val.selected = val.name === value
            })
        })  
    }
   }


  import getPowerSet from '@/vender/power-set'
  const spliter = '★'
  //得到路径字典对象
  const getPathMap = (skus) => {
        //存储子集的路径字典
        const pathMap = {}
        //在skus里筛选出有效数据
        skus.forEach(sku => {
            if(sku.inventory > 0) {
                //计算当前有库存的sku子集
                //可选值数组
                const valueArr = sku.specs.map(val => val.valueName)
                //可选数组的子集，调用计算方法
                const valueArrPowerSet = getPowerSet(valueArr)
                //生成路径字典
                //遍历子集，往pathMap插入数据。
                valueArrPowerSet.forEach(arr => {
                    //根据arr得到字符串的key
                    //arr.join()把数组中的所有元素转换为一个字符串, ()里面可添加分隔符
                    const key  = arr.join(spliter)
                    //已经有key往数组中追加
                    if(pathMap[key]) {
                        pathMap[key].push(sku.id)
                    } else {
                        //没有key设置数组
                        pathMap[key] = [sku.id]
                    }
                })
            }
        })
        return pathMap
    }

 //得到当前选中规格集合
 const getSelectedArr = (specs) => {
    //选中值的数组
    const selectedArr = []
    specs.forEach(spec => {
        const selectedVal = spec.values.find(val => val.selected)
        selectedArr.push(selectedVal? selectedVal.name: undefined)
    })
    console.log(selectedArr);
    return selectedArr
 }
 
 //更新按钮的禁用状态
 //点击按钮前需更新状态，点击后也需要更新状态
 const updateDisabledStatus = (specs, pathMap) => {
    specs.forEach((spec, i) => {
        const selectedArr = getSelectedArr(specs)
        spec.values.forEach(val => {
            //已选中的按钮不用判断
            if(val.name === selectedArr[i]) return false
            //未选中的替换对应的值
            selectedArr[i] = val.name
            //过滤无效值得到key
            const key = selectedArr.filter(v => v).join(spliter)
            //设置禁用状态
            val.disabled = !pathMap[key]
        })
    }) 

 }
  </script>
  <style scoped lang="less">
  .sku-state-mixin () {
    border: 1px solid #e4e4e4;
    margin-right: 10px;
    cursor: pointer;
    &.selected {
      border-color: @xtxColor;
    }
    &.disabled {
      opacity: 0.6;
      border-style: dashed;
      cursor: not-allowed;
    }
  }
  .goods-sku {
    padding-left: 10px;
    padding-top: 20px;
    dl {
      display: flex;
      padding-bottom: 20px;
      align-items: center;
      dt {
        width: 50px;
        color: #999;
      }
      dd {
        flex: 1;
        color: #666;
        > img {
          width: 50px;
          height: 50px;
          .sku-state-mixin ();
        }
        > span {
          display: inline-block;
          height: 30px;
          line-height: 28px;
          padding: 0 20px;
          .sku-state-mixin ();
        }
      }
    }
  }
  </style>